﻿#include <sys/vfs.h>
#include <sys/stat.h>
#include <dirent.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <unistd.h>
#include <fstream>
#include <map> // 包含map头文件
#include <sstream>
#include <stdexcept>
#include <filesystem>

// const std::string ROOT_DIR = "/mnt/sdcard";
//  const std::string ROOT_DIR = "/";
//  const double MIN_FREE_PERCENT = 10.0;
//  const double MAX_FREE_PERCENT = 15.0;
//  const int MAX_FILES_TO_DELETE = 10;

double stringToDouble(const std::string &str)
{
	try
	{
		return std::stod(str);
	}
	catch (const std::invalid_argument &e)
	{
		// 处理无效参数异常
		// throw e; // 或者其他错误处理
		return std::stod("0"); // 处理异常时返回会默认值
	}
	catch (const std::out_of_range &e)
	{
		// 处理转换结果超出范围异常
		// throw e; // 或者其他错误处理
		return std::stod("0"); // 处理异常时返回会默认值
	}
}

bool isDirectory(const std::string &path)
{
	struct stat s;
	if (stat(path.c_str(), &s) == 0)
	{
		return S_ISDIR(s.st_mode);
	}
	return false;
}

void listFiles(const std::string &path, std::vector<std::string> &files, std::vector<std::string> &folders)
{
	DIR *dir = opendir(path.c_str());
	if (dir == nullptr)
	{
		return;
	}
	struct dirent *entry;
	while ((entry = readdir(dir)) != nullptr)
	{
		if (entry->d_name[0] == '.')
		{
			continue;
		}
		std::string fullPath = path + "/" + entry->d_name;
		if (isDirectory(fullPath))
		{
			listFiles(fullPath, files, folders);
			folders.push_back(fullPath);
		}
		else
		{
			files.push_back(fullPath);
		}
	}
	closedir(dir);
}

std::string remove_filename(const std::string &path)
{
	std::filesystem::path p(path);
	return p.parent_path().string();
}

bool sortByLastModifiedTime(const std::string &a, const std::string &b)
{
	struct stat s1, s2;
	// 尝试获取文件 a（由 a.c_str() 提供的C风格字符串表示）的状态信息
	if (stat(a.c_str(), &s1) == -1 || stat(b.c_str(), &s2) == -1)
	{
		return false;
	}
	return s1.st_mtime < s2.st_mtime;
}

bool deleteFile(const std::string &path)
{
	// std::filesystem::remove函数可以用来删除文件或空文件夹。但是，如果文件夹非空，直接使用remove函数会失败
	return remove(path.c_str()) == 0;
}
namespace fs = std::filesystem;
bool is_directory_empty(const fs::path &dir_path)
{
	if (!fs::exists(dir_path) || !fs::is_directory(dir_path))
	{
		return false; // 路径不存在或不是目录
	}
	for (const auto &entry : fs::directory_iterator(dir_path))
	{
		if (entry.is_regular_file() || entry.is_directory())
		{
			return false; // 发现文件或子目录，因此目录不为空
		}
	}
	return true; // 遍历完成且未发现任何文件或子目录，因此目录为空
}

unsigned long fileSize(const std::string &path)
{
	unsigned long filesize = -1;
	struct stat statbuff;
	if (stat(path.c_str(), &statbuff) < 0)
	{
		return filesize;
	}
	else
	{
		filesize = statbuff.st_size;
	}
	return filesize;
}

int main()
{
	std::ifstream configFile("LinuxDiskMonitoring.ini");
	std::string line;
	std::map<std::string, std::string> config;
	if (configFile.is_open())
	{
		while (getline(configFile, line))
		{
			std::istringstream is_line(line);
			std::string key;
			if (getline(is_line, key, '='))
			{
				std::string value;
				if (getline(is_line, value))
				{
					config[key] = value;
				}
				else
				{
					std::cerr << "配置项格式错误: " << line << std::endl;
				}
			}
		}
		configFile.close();
	}
	else
	{
		std::cout << "无法打开配置文件" << std::endl;
	}
	// 使用配置信息
	// 例如: 打印所有配置项

	// for (const auto& pair : config) {
	// std::cout << pair.first << " = " << pair.second << std::endl;
	std::string ROOT_DIR = config["ROOT_DIR"];
	double MIN_FREE_PERCENT = stringToDouble(config["MIN_FREE_PERCENT"]);
	double MAX_FREE_PERCENT = stringToDouble(config["MAX_FREE_PERCENT"]);
	int MAX_FILES_TO_DELETE = stringToDouble(config["MAX_FILES_TO_DELETE"]);
	int TIME = stringToDouble(config["TIME"]);

	// }
	std::vector<std::string> files;		 // 文件列表
	std::vector<std::string> folders;	 // 文件夹列表

	while (true)
	{
		struct statfs diskInfo;
		if (statfs(ROOT_DIR.c_str(), &diskInfo) == -1)
		{
			std::cerr << "Failed to get disk info" << std::endl;
			break;
		}
		unsigned long long totalBytes = diskInfo.f_blocks * diskInfo.f_bsize;
		unsigned long long freeBytes = diskInfo.f_bfree * diskInfo.f_bsize;
		double freePercent = (double)freeBytes / totalBytes * 100;
		 if (freePercent > MAX_FREE_PERCENT)
		 {
		 	std::cout << "totalBytes:" << totalBytes << std::endl;
		 	std::cout << "freeBytes:" << freeBytes << std::endl;
		 	std::cout << "freePercent:" << freePercent << std::endl;
		 	sleep(TIME);
		 	continue;
		 }
		files.clear();
		listFiles(ROOT_DIR, files, folders); // 提供 ROOT_DIR 中的文件,文件夹列表
		std::sort(files.begin(), files.end(), sortByLastModifiedTime);
		int numFilesToDelete = std::min((int)files.size(), MAX_FILES_TO_DELETE);
		for (int i = 0; i < numFilesToDelete; i++)
		{
			if (!deleteFile(files[i]))
			{
				std::cerr << "Failed to delete file: " << files[i] << std::endl;
			}
			std::string str = remove_filename(files[i]);
			std::cout << str << std::endl;
			deleteFile(str); // 删除空文件夹

			freeBytes += fileSize(files[i]);
			freePercent = (double)freeBytes / totalBytes * 100;
			if (freePercent > MAX_FREE_PERCENT)
			{
				break;
			}
			sleep(10);
		}
		// for (int i = 0; i < (int)folders.size(); i++)
		// {
		// 	// if (is_directory_empty)
		// 	// {
		// 	if (!deleteFile(folders[i]))
		// 	{
		// 		std::cout << "文件夹不为空：" << folders[i] << std::endl;
		// 	}
		// 	else
		// 	{
		// 		std::cout << "空文件夹" << folders[i] << std::endl;
		// 	}


		// 	// }
		// }
	}
	return 0;
}
